package com.itheima.reggie.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.dto.dish.DishAddDTO;
import com.itheima.reggie.entity.dto.dish.DishUpdateDTO;
import com.itheima.reggie.entity.vo.DishVo;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.web.R;
import com.itheima.reggie.web.exception.BusinessException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.itheima.reggie.utils.RedisConstant.FRONT_DISH;

/**
 * 菜品控制层
 *
 * @Name : DishController
 * @Author : WuQiang
 * @Date : 2022-08-14 19:31
 * @Description : 菜品控制层
 */
@Slf4j
@RestController
@RequestMapping("/dish")
@Api(tags = "菜品管理")
public class DishController {
    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 菜品分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    @ApiOperation(value = "分页查询菜品")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page",value = "页码",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页记录数",required = true),
            @ApiImplicitParam(name = "name",value = "菜品名称",required = false)
    })
    public R getPage(Long page, Long pageSize, String name) {
        //参数校验
        if (ObjectUtils.isEmpty(page) || ObjectUtils.isEmpty(pageSize)) {
            throw new BusinessException("参数非法");
        }
        if (page <= 0) {
            page = 1L;
        }
        if (pageSize <= 0) {
            pageSize = 1L;
        }
        return dishService.getPage(page, pageSize, name);
    }

    /**
     * 菜品状态修改
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    @ApiOperation(value = "菜品状态修改")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status",value = "修改的状态",required = true),
            @ApiImplicitParam(name = "ids",value = "修改的菜品id数组",required = true)
    })
    public R bulkOperations(@PathVariable Integer status, Long[] ids) {
        //参数校验
        if (ObjectUtils.isEmpty(status) || ObjectUtils.isEmpty(ids)) {
            throw new BusinessException("参数非法！");
        }
        Boolean result = dishService.bulkOperations(status, ids);
        if (result) {
            return R.success("操作成功");
        }
        return R.error("操作失败");
    }

    /**
     * 新增菜品
     * @param dto
     * @return
     */
    @PostMapping
    @ApiOperation(value = "新增菜品")
    public R addDish(@RequestBody DishAddDTO dto) {
        //参数校验
        Boolean result = dishService.saveWithName(dto);
        String key = FRONT_DISH + dto.getCategoryId() + "_1";
        //删除redis缓存
        redisTemplate.delete(key);

        if (result) {
            return R.success("新增菜品成功");
        }
        return R.error("新增菜品失败");
    }

    /**
     * 通过id查询回显菜品信息
     *
     * @param id
     * @return
     */
    @GetMapping("{id}")
    @ApiOperation(value = "通过id查询回显菜品信息")
    @ApiImplicitParam(name = "id",value = "菜品id",required = true)
    public R getById(@PathVariable Long id) {
        //参数校验
        if (ObjectUtils.isEmpty(id)) {
            throw new BusinessException("参数非法");
        }
        DishVo dishVo = dishService.getDishAndDishFlaverById(id);
        return R.success("查询菜品成功", dishVo);
    }


    /**
     * 修改菜品
     * @param dto
     * @return
     */
    @PutMapping
    @ApiOperation(value = "修改菜品")
    public R update(@RequestBody DishUpdateDTO dto) {
        log.info("修改菜品相关参数", dto);
        //参数校验
        //获取数据库的菜品categoryId
        Dish dbDish = dishService.getById(dto.getId());
        Long dbCategoryId = dbDish.getCategoryId();
        String key = FRONT_DISH + dbCategoryId + "_1";
        //修改逻辑
        Boolean result = dishService.updateDishAndDishFlavor(dto);
        //删除redis中的缓存
        redisTemplate.delete(key);
        //判断用户是否修改菜品的类别
        if (!dbCategoryId.equals(dto.getCategoryId())) {
            key = FRONT_DISH + dto.getCategoryId() + "_1";
            redisTemplate.delete(key);
        }
        if (result) {
            return R.success("修改菜品成功");
        }
        return R.error("修改菜品失败");
    }


    /**
     * 逻辑删除与批量删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("删除菜品")
    @ApiImplicitParam(name = "ids",value = "批量删除菜品id数组")
    public R delete(Long[] ids) {
        //参数校验
        List<Long> idList = Arrays.asList(ids);
        if (idList == null || idList.size() <= 0) {
            throw new BusinessException("参数异常");
        }
        Boolean result = dishService.deleteByIds(idList);

        if (result) {
            return R.success("删除菜品成功");
        }
        return R.error("删除菜品失败");
    }

    /**
     * 根据套餐id查询菜品列表回显
     *
     * @return
     */
    @GetMapping("/list")
    @ApiOperation(value = "根据套餐id查询菜品集合")
    public R findBycategoryId(Dish dish) {
        //先查询redis缓存
        String key = FRONT_DISH + dish.getCategoryId() + "_1";
        List<DishVo> dishVoList = (List<DishVo>) redisTemplate.opsForValue().get(key);
        if (dishVoList != null) {
            log.info("查询redis缓存得到该数据");
            //如果缓存中有直接返回
            return R.success("根据套餐id查询菜品列表成功", dishVoList);
        }
        //缓存中不存在查询数据库

//        log.info("根据套餐id查询菜品列表，id：{}", dish);
        log.info("查询数据库得到该数据");
        LambdaQueryWrapper<Dish> wrapper = Wrappers.lambdaQuery(Dish.class);
        Long categoryId = dish.getCategoryId();
        Integer status = dish.getStatus();
        //根据套餐id查询菜品，并且当前在起售状态
        wrapper.eq(!ObjectUtils.isEmpty(categoryId), Dish::getCategoryId, categoryId)
                .eq(!ObjectUtils.isEmpty(status), Dish::getStatus, status);
        List<Dish> dishList = dishService.list(wrapper);
        //返回 菜品以及菜品管理口味信息
        dishVoList = dishList.stream().map(item -> {
            DishVo dishVo = new DishVo();
            BeanUtils.copyProperties(item, dishVo);
            //根据菜品id查询口味表对应的口味
            List<DishFlavor> dishFlavorList = dishFlavorService.list(Wrappers.lambdaQuery(DishFlavor.class)
                    .eq(DishFlavor::getDishId, dishVo.getId()));
            //添加进返回结果
            dishVo.setFlavors(dishFlavorList);
            //查询套餐名称
            Category category = categoryService.getById(categoryId);
            dishVo.setCategoryName(category.getName());
            //通过菜品id查询
            return dishVo;
        }).collect(Collectors.toList());

        //将菜品信息缓存在redis中
        redisTemplate.opsForValue().set(key, dishVoList);
        //返回结果
        return R.success("根据套餐id查询菜品列表成功", dishVoList);
    }
}
